package com.augurit.common.sysfile.web;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;

import javax.servlet.ServletOutputStream;

import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.beans.factory.annotation.Autowired;
import org.springside.modules.orm.Page;

import com.augurit.common.base.action.ExtCrudActionSupport;
import com.augurit.common.base.form.Attachment;
import com.augurit.common.base.form.ResultForm;
import com.augurit.common.constant.SystemConstant;
import com.augurit.common.sysfile.service.ISysFileService;
import com.augurit.common.sysfile.web.form.SysFileForm;
import com.augurit.common.util.ExtUtils;
import com.augurit.common.util.FileUtils;

/**
 * 普通附件管理Action类
 */
@SuppressWarnings("serial")
@Results({
	@Result(name = ExtCrudActionSupport.RELOAD, location = "${redirectUrl}", type = "redirect"),
	@Result(name = ExtCrudActionSupport.SUCCESS, location = "/common/sysfile/sys-file.jsp"),
	@Result(name = SysFileAction.EDIT_FORM_AND_DOC, location = "/common/sysfile/public/EditFormAndDoc.jsp"),
	@Result(name = SysFileAction.EDIT_OFFICE_DOC, location = "/resources/components/ntko/EditOfficeDoc.jsp"),
	@Result(name = SysFileAction.ATTACHMENT_LIST_IFRAME, location = "/common/sysfile/public/attachment-mgmt-iframe.jsp")
})
public class SysFileAction extends ExtCrudActionSupport<SysFileForm> {

	private static final String ATTACHMENT_LIST_IFRAME = "attachment_list_iframe";		//附件列表，iframe
	private static final String EDIT_OFFICE_DOC = "EDIT_OFFICE_DOC";
	private static final String EDIT_FORM_AND_DOC= "EDIT_FORM_AND_DOC";
	
	// Service 引用
	@Autowired
	private ISysFileService sysFileService;
	
	// 基本属性
	private SysFileForm form;
	private Long sysFileId;
	private Long[] sysFileIds;
	private Page<SysFileForm> page = new Page<SysFileForm>();
	private String redirectUrl;		//对附件作上传、删除等操作后要跳转回业务模块的指定地址
	
	private Attachment document; 	//文档文件对象

	
	/**
	 * 附件列表查询
	 */
	@Override
	public String list() throws Exception {
		ExtUtils.initPageFromExtGridParam(this.getRequest(), page);
		sysFileService.search(page, form);
		this.extRenderGridJson(page);
		return null;
	}
	
	/**
	 * 新增或编辑附件页面
	 */
	@Override
	public String input() throws Exception {
		this.extRenderFormJson(form);
		return null;
	}

	/**
	 * 保存附件信息
	 */
	@Override
	public String save() throws Exception {
		sysFileService.save(form, this.getLoginUser().getUser().getUserName());
		this.extRenderSuccess();
		return null;
	}

	/**
	 * 删除一个或多个附件记录
	 */
	@Override
	public String delete() throws Exception {
		for(int i = 0; i < sysFileIds.length; i++){
			this.delete(sysFileService.get(sysFileIds[i]));
		}
		return null;
	}
	
	/**
	 * 从服务器磁盘读取附件文件内容
	 */
	public String readAttachment() throws Exception {
		
		InputStream in = null;
    	ServletOutputStream ou = null;
    	
    	//获取附件路径和附件名称
    	String filePath = form.getFilePath();
    	String fileName = form.getFileName();
    	if(filePath == null || filePath.trim().length() == 0
    			|| fileName == null || fileName.trim().length() == 0)
    		return null;
    	
    	//根路径
    	String directoryPath = this.getApplication().getRealPath("/");
    	//模板文件存放的绝对路径
    	String ntkoTemplateFilePath = directoryPath + SystemConstant.NTKO_TEMPLATE_FILEPATH;
    	
        try {
        	File file = null;
        	
        	//如果是新建附件文件，且该附件文件为office类型的文件，则根据文件的扩展名新建一个office类型的模板文件
            if(FileUtils.isNewFile(filePath, fileName, false, directoryPath, true) && FileUtils.isFileCanBeOpenedByNtko(fileName)){
            	//获取模板文件
            	file = FileUtils.newTemplateFile(fileName, ntkoTemplateFilePath);
            }
            //否则打开附件文件
            else{
            	file = FileUtils.openFile(filePath, fileName, false, directoryPath, true, true);
            }
            
        	//重置response
            this.getResponse().reset();
            this.getResponse().setContentType("application/octet-stream");
            
            fileName = FileUtils.reEncodeChineseFileName(fileName, this.getRequest());
            this.getResponse().setHeader("Content-Disposition","attachment; filename=" + fileName);

            in = new BufferedInputStream(new FileInputStream(file), BUFFER_SIZE);
            ou = this.getResponse().getOutputStream();
            byte[] buffer = new byte[BUFFER_SIZE];
            int n = 0;
            while ((n = in.read(buffer)) != -1) {
                ou.write(buffer, 0, n);
            }
            
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
			try {
				if(in != null) {
					in.close();
				}
				if(ou != null) {
					ou.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
        
		return null;
	}
	
	/**
	 * 上传文档至服务器磁盘并更新文档附件记录
	 */
	public String uploadAttachment() throws Exception{
		boolean success = this.upload(form, document);
		if(success)
			this.extRenderSuccess();
		else
			this.extRenderFailture();
		return null;
	}
	
	/**
	 * 上传文档至服务器磁盘并更新文档附件记录
	 */
	public String saveFormAndAttachment() throws Exception{
		ResultForm result = this.saveFormAndAttachment(form, document);
		this.renderJson(result, SystemConstant.ENCODING_GBK);
		return null;
	}
	
	/**
	 * 打开NTKO控件在线编辑文档页面
	 */
	public String editOfficeDoc() throws Exception{
		return EDIT_OFFICE_DOC;
	}
	
	
	/**
	 * 打开NTKO控件在线编辑文档页面
	 */
	public String editFormAndDoc() throws Exception{
		String directoryPath = this.getApplication().getRealPath("/");
		
		//如果磁盘上不存在文件，把表单上setIsAttachmentContentChange设置为内容改变状态
		if(!FileUtils.isFileExist(form.getFilePath(), form.getFileName(), false, directoryPath, true)){
			form.setIsAttachmentContentChange(true);
		}
		
		return EDIT_FORM_AND_DOC;
	}
	
	/**
	 * 将文档附件转换为HTML文件上传至服务器磁盘并更新文档附件记录
	 */
	public String saveAsHtml() throws Exception{
		
		//更改为HTML格式的新增的form对象
		FileUtils.changeToHtml(form);
		
		boolean success = this.upload(form, document);

		if(success)
			this.renderText("已成功另存为HTML文件！", SystemConstant.ENCODING_GBK);
		else
			this.renderText("另存为HTML文件失败！", SystemConstant.ENCODING_GBK);
		return null;
	}
	
	/**
	 * 将文档附件转换为PDF文件上传至服务器磁盘并更新文档附件记录
	 */
	public String saveAsPdf() throws Exception{
		
		//更改为PDF格式的新增的form对象
		FileUtils.changeToPdf(form);
		
		boolean success = this.upload(form, document);

		if(success)
			this.renderText("已成功另存为PDF文件！", SystemConstant.ENCODING_GBK);
		else
			this.renderText("另存为PDF文件失败！", SystemConstant.ENCODING_GBK);
		return null;
	}
	
	
	/**
	 * 给业务模块上传附件
	 */
	public String addAttachment() throws Exception {
		List<Attachment> attachments = this.getAttachmentList();
		if(attachments != null){
			for(Attachment attachment : attachments){
				//上传附件
				boolean success = this.upload(form.getEntity(), form.getEntityId(), form.getFilePath(), null, null, null, attachment);
				if(!success){
					this.renderText("上传附件失败", SystemConstant.ENCODING_GBK);
					return null;
				}
			}
		}
		
		redirectUrl = this.getRootPath() + redirectUrl; 
		return RELOAD;
	}
	
	/**
	 * 给业务模块上传附件
	 * 注意：结合swfupload控件使用
	 */
	public String addAttachmentForSwfupload() throws Exception {
		List<Attachment> attachments = this.getAttachmentList();
		
		if(attachments != null){
			for(Attachment attachment : attachments){
				//上传附件
				boolean success = this.upload(form.getEntity(), form.getEntityId(), form.getFilePath(), null, null, null, attachment);
				if(success == false)
					throw new RuntimeException();
			}
		}
		
		this.renderText("successed");
		return null;
	}
	
	
	/**
	 * 删除业务模块的附件
	 */
	public String deleteAttachment() throws Exception {
		//删除附件
		boolean success = this.delete(sysFileId);
		if(!success){
			this.renderText("删除附件失败", SystemConstant.ENCODING_GBK);
			return null;
		}
		
		redirectUrl = this.getRootPath() + redirectUrl;
		return RELOAD;
	}
	
	/**
	 * 删除业务模块的一个或者多个附件
	 * @return
	 * @throws Exception
	 */
	public String deleteMoreAttachment() throws Exception {
		if(sysFileIds != null && sysFileIds.length > 0){
			for(Long id: sysFileIds){
				//删除附件
				boolean success = this.delete(id);
				if(!success){
					this.renderText("删除附件失败", SystemConstant.ENCODING_GBK);
					return null;
				}
			}
		}
		redirectUrl = this.getRootPath() + redirectUrl;
		return RELOAD;
	}

	/**
	 * 显示附件列表
	 * @return
	 * @throws Exception
	 */
	public String showAttachmentsIframe() throws Exception{
		return ATTACHMENT_LIST_IFRAME;
	}
	
	
	public SysFileForm getModel() {
		return form;
	}

	@Override
	protected void prepareModel() throws Exception {
		if(sysFileId != null)
			form = sysFileService.get(sysFileId);
		else
			form = new SysFileForm();
	}
	
	// 属性getter和setter方法

	public Page<SysFileForm> getPage() {
		return page;
	}

	public void setPage(Page<SysFileForm> page) {
		this.page = page;
	}

	public Long[] getSysFileIds() {
		return sysFileIds;
	}

	public void setSysFileIds(Long[] sysFileIds) {
		this.sysFileIds = sysFileIds;
	}

	public SysFileForm getForm() {
		return form;
	}

	public void setForm(SysFileForm form) {
		this.form = form;
	}

	public Attachment getDocument() {
		return document;
	}

	public void setDocument(Attachment document) {
		this.document = document;
	}

	public String getRedirectUrl() {
		return redirectUrl;
	}

	public void setRedirectUrl(String redirectUrl) {
		this.redirectUrl = redirectUrl;
	}

	public Long getSysFileId() {
		return sysFileId;
	}

	public void setSysFileId(Long sysFileId) {
		this.sysFileId = sysFileId;
	}
}
